import os.path
import re
from wsgiref.simple_server import make_server

BASE_DIR = os.path.abspath(__file__)  # 当前程序文件所在的绝对路径
BASE_DIR_father = os.path.dirname(BASE_DIR)  # 让指定路径上升一级(变为其父路径)


# 要实现多url：
# 1.路由分发器，负责把url匹配到对应的函数
# 2.开发对应业务函数
# 3.新的请求先经过路由分发器，如果找到对应function就执行，否则就返回404
def book(environment, start_response):
    print("book page")

    # 假定使用/static/开头的url请求图片及其他特殊内容
    data = """
        <h1 style=color:red>欢迎来到***专区</h1>
            <img src='/static/imgs/test.png'/>
        <p style=font-size:30px;color:yellow>上路飞学城，看尽天下 A pian</p>
    """
    resp_body = [bytes(data, encoding='utf-8'), ]  # 列表格式：设置响应体内容
    return resp_body  # 返回响应体


def cloth(environment, start_response):
    print("cloth page")

    resp_body = [bytes("<h1 style=color:blue>cloth page。。。</h1>", encoding='utf-8'), ]  # 列表格式：设置响应体内容
    return resp_body  # 返回响应体


# 路由分发器
def url_distributor():
    urls = {
        '/book': book,
        '/cloth': cloth,
    }

    return urls  # 返回路由字典


# 处理图片等特殊请求
def img_handler(request_url):
    # 更正文件真实路径，方法很多，此处使用正则匹配进行替换
    img_path = re.sub('/static', '/static_data', request_url)
    img_abs_path = "%s%s" % (BASE_DIR_father, img_path)  # 路径拼接成为绝对路径,拼接方法很多，此处使用%格式化方法
    # print(img_abs_path)
    data, status = None, 1  # data默认为None:不存在，状态为1：有错
    if os.path.isfile(img_abs_path):  # 判断图片文件是否存在

        f = open(img_abs_path, "rb")
        data = f.read()  # 图片文件内容
        status = 0  # 文件存在则状态为0
        f.close()

    return [data, status]  # 以列表形式返回，0代表没错，1代表有错


# run_server必须实现两个参数,否则会报错"TypeError: run_server() takes 0 positional arguments but 2 were given"
# 因为默认make_server封装了两个参数传递过来，第一个是浏览器请求头(环境)，第二个是一个方法，用于向客户端返回内容
def run_server(environment, start_response):
    print(environment)

    url_list = url_distributor()  # 拿到url字典
    requests_url = environment.get("PATH_INFO")  # 环境字典的'PATH_INFO'键对应的值是url
    print('request url', requests_url)

    # 处理对应url
    if requests_url in url_list:
        # 流程和本质上的socket一致
        start_response("200 OK", [('Content-Type', 'text/html;charset=utf-8')])  # 固定格式:设置响应头
        resp_body = url_list[requests_url](environment, start_response)  # 调用对应处理方法获取响应体内容
    elif requests_url.startswith("/static/"):  # 判断url开头是static请求
        img_data, img_status = img_handler(requests_url)  # 根据请求信息返回图片等特殊内容
        if img_status == 0:  # 图片有内容，注意图片的响应头类型应该为jpeg
            start_response("200 OK", [('Content-Type', 'text/jpeg;charset=utf-8')])  # 固定格式:设置响应头
            resp_body = [img_data, ]  # 列表格式：设置响应体内容
        else:
            start_response("404 ", [('Content-Type', 'text/jpeg;charset=utf-8')])
            resp_body = [bytes("", encoding='utf-8'), ]
    else:
        # 未找到页面
        start_response("404 ", [('Content-Type', 'text/html;charset=utf-8')])  # 固定格式:设置响应头
        resp_body = [bytes("<h1 style=font-size:50px>404, page not found!</h1>", encoding='utf-8'), ]  # 列表格式：设置响应体内容

    return resp_body  # 返回响应体


s = make_server('localhost', 8000, run_server)  # 接收请求，让请求经过run_server
s.serve_forever()  # 启动服务，相当于死循环，一直监听指定端口
